<template>
  <div class="home">
    <div id="container" style="width:1000px;height:600px;"></div>
  </div>
</template>

<script>
import { Graph, Node, Edge, Shape } from "@antv/x6";
import { Layout } from "@antv/layout";

// 定义节点
class TreeNode extends Node {
  collapsed = false;

  postprocess() {
    this.toggleCollapse(false);
  }

  isCollapsed() {
    return this.collapsed;
  }

  toggleButtonVisibility(visible) {
    this.attr("buttonGroup", {
      display: visible ? "block" : "none"
    });
  }

  toggleCollapse(collapsed) {
    const target = collapsed == null ? !this.collapsed : collapsed;
    if (!target) {
      this.attr("buttonSign", {
        d: "M 1 5 9 5 M 5 1 5 9",
        strokeWidth: 1.6
      });
    } else {
      this.attr("buttonSign", {
        d: "M 2 5 8 5",
        strokeWidth: 1.8
      });
    }
    this.collapsed = target;
  }
}

TreeNode.config({
  zIndex: 2,
  markup: [
    {
      tagName: "g",
      selector: "buttonGroup",
      children: [
        {
          tagName: "rect",
          selector: "button",
          attrs: {
            "pointer-events": "visiblePainted"
          }
        },
        {
          tagName: "path",
          selector: "buttonSign",
          attrs: {
            fill: "none",
            "pointer-events": "none"
          }
        }
      ]
    },
    {
      tagName: "rect",
      selector: "body"
    },
    {
      tagName: "text",
      selector: "label"
    }
  ],
  attrs: {
    body: {
      refWidth: "100%",
      refHeight: "100%",
      strokeWidth: 1,
      fill: "#ffffff",
      stroke: "#ccc"
    },
    label: {
      textWrap: {
        ellipsis: true,
        width: -10
      },
      textAnchor: "middle",
      textVerticalAnchor: "middle",
      refX: "50%",
      refY: "50%",
      fontSize: 12
    },
    buttonGroup: {
      refX: "100%",
      refY: "50%"
    },
    button: {
      fill: "#ffffff",
      stroke: "#ccc",
      x: -0,
      y: -8,
      height: 16,
      width: 16,
      rx: 10,
      ry: 10,
      cursor: "pointer",
      event: "node:collapse"
    },
    buttonSign: {
      refX: 3,
      refY: -5,
      stroke: "#ccc",
      strokeWidth: 1.6
    }
  }
});

// 定义边
class TreeEdge extends Shape.Edge {
  isHidden() {
    const node = this.getTargetNode();
    return !node || !node.isVisible();
  }
}

TreeEdge.config({
  zIndex: 1,
  attrs: {
    line: {
      stroke: "#ccc",
      strokeWidth: 1,
      targetMarker: null
    }
  }
});

// 注册
Node.registry.register("tree-node", TreeNode, true);
Edge.registry.register("tree-edge", TreeEdge, true);

export default {
  name: "Home",
  mounted() {
    // 初始化画布
    const graph = new Graph({
      container: document.getElementById("container"),
      grid: 1,
      // async: true,
      // frozen: true,
      scroller: true
      // interacting: false,
      // sorting: "approx",
      // background: {
      //   color: "#f5f5f5"
      // },
      // connecting: {
      //   anchor: "orth",
      //   connector: "rounded",
      //   connectionPoint: "boundary",
      //   router: {
      //     name: "er",
      //     args: {
      //       offset: 24,
      //       direction: "H"
      //     }
      //   }
      // }
    });

    graph.on("node:collapse", ({ node }) => {
      node.toggleCollapse();
      const collapsed = node.isCollapsed();
      const run = pre => {
        const succ = graph.getSuccessors(pre, { distance: 1 });
        if (succ) {
          succ.forEach(node => {
            node.toggleVisible(!collapsed);
            if (!node.isCollapsed()) {
              run(node);
            }
          });
        }
      };
      run(node);
    });

    const data = {
      nodes: [],
      edges: []
    };

    for (let i = 1; i <= 12; i++) {
      data.nodes.push({
        id: i + "",
        shape: "rect",
        width: 60,
        height: 30,
        attrs: {
          body: {
            radius: 4
          },
          label: {
            textWrap: {
              text: i
            }
          }
        }
      });
    }

    data.edges.push(
      ...[
        {
          source: "1",
          target: "2",
          attrs: {
            line: {
              stroke: "#ccc",
              strokeWidth: 1,
              targetMarker: null
            }
          }
        },
        {
          source: "2",
          target: "3",
          attrs: {
            line: {
              stroke: "#ccc",
              strokeWidth: 1,
              targetMarker: null
            }
          }
        },
        {
          source: "2",
          target: "4",
          attrs: {
            line: {
              stroke: "#ccc",
              strokeWidth: 1,
              targetMarker: null
            }
          }
        },
        {
          source: "4",
          target: "5",
          attrs: {
            line: {
              stroke: "#ccc",
              strokeWidth: 1,
              targetMarker: null
            }
          }
        },
        {
          source: "4",
          target: "6",
          connector: {
            name: "rounded",
            args: {}
          },
          attrs: {
            line: {
              stroke: "#ccc",
              strokeWidth: 1,
              targetMarker: null
            }
          }
        },
        {
          source: "4",
          target: "7",
          attrs: {
            line: {
              stroke: "#ccc",
              strokeWidth: 1,
              targetMarker: null
            }
          }
        },
        {
          source: "4",
          target: "8",
          attrs: {
            line: {
              stroke: "#ccc",
              strokeWidth: 1,
              targetMarker: null
            }
          }
        },
        {
          source: "5",
          target: "9",
          attrs: {
            line: {
              stroke: "#ccc",
              strokeWidth: 1,
              targetMarker: null
            }
          }
        },
        {
          source: "6",
          target: "10",
          attrs: {
            line: {
              stroke: "#ccc",
              strokeWidth: 1,
              targetMarker: null
            }
          }
        },
        {
          source: "7",
          target: "11",
          attrs: {
            line: {
              stroke: "#ccc",
              strokeWidth: 1,
              targetMarker: null
            }
          }
        },
        {
          source: "8",
          target: "12",
          attrs: {
            line: {
              stroke: "#ccc",
              strokeWidth: 1,
              targetMarker: null
            }
          }
        }
      ]
    );

    const dagreLayout = new Layout({
      type: "dagre",
      rankdir: "LR",
      align: "DR",
      ranksep: 30,
      nodesep: 15,
      controlPoints: true
    });
    const newModel = dagreLayout.layout(data);

    graph.fromJSON(newModel);

    // graph.resetCells([...nodes, ...edges]);

    // graph.unfreeze({
    //   progress({ done }) {
    //     if (done) {
    //       const time = new Date().getTime() - start;
    //       console.log(time);
    //       graph.unfreeze({
    //         batchSize: 50
    //       });
    //       graph.zoomToFit({ padding: 24 });
    //     }
    //   }
    // });
  }
};
</script>
